using System;
using NBusiness.Data;
using System.Reflection;
using System.IO;
using System.Security.Policy;
using System.Runtime.Hosting;

namespace NBusiness.Utilities
{
    [Serializable]
    public static class TypeLoader
    {
        public static T Load<T>(string assemblyName, string typeName)
        {
            T t = default(T);
            try
            {
                Type type = null;
                bool loaded = false;
                foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
                {
                    if (a.FullName == assemblyName || a.GetName().Name == assemblyName)
                    {
                        loaded = true;
                        type = a.GetType(typeName);
                        break;
                    }
                }

                if (!loaded)
                {
                    Assembly a = Assembly.LoadFrom(assemblyName);
                    type = a.GetType(typeName);
                }

                if (type != null && typeof(T).IsAssignableFrom(type))
                    t = (T)Activator.CreateInstance(type);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }

            return t;
        }

        /// <summary>
        /// Find's a type by Fullname (namespace + name) in any assembly loaded into 
        /// the current AppDomain.
        /// </summary>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static Type FindType(string fullTypeName)
        {
            return FindType(fullTypeName, AppDomain.CurrentDomain);
        }

        public static Type FindType(string fullTypeName, AppDomain appDomain)
        {
            Type t = Type.GetType(fullTypeName);
            if (t == null)
            {
                foreach (Assembly a in appDomain.GetAssemblies())
                {
                    t = a.GetType(fullTypeName, false, true);
                    if (t != null) break; 
                }
            }
            return t;
        }
    }
}